<template>
  <a-row>
    <a-col :span="12">
      <div>
        <div>
          <a-input v-focus placeholder="我会自己获取焦点"></a-input>
        </div>
        <a-divider></a-divider>
        <!-- 在 main.js 中使用全局注册指令 -->
        <div>
          <a-input v-updateColor value="看看我是什么颜色"></a-input>
        </div>
        <!-- 钩子函数测试 -->
        <a-divider></a-divider>
        <div>
          <a-input
            v-myDirective
            v-model:value="value"
            id="myDirective"
          ></a-input>
        </div>
        <!-- 传值 -->
        <a-divider></a-divider>
        <div>
          <a-button type="primary" @click="change">change</a-button>
          <p></p>
          <!-- 当这个组件的值变化后， myDirective 组件也会发生更新 -->
          <a-input
            v-example:[foo].bar="baz"
            v-model:value="baz"
            id="example"
          ></a-input>
        </div>
        <!-- myIf -->
        <a-divider></a-divider>
        <div>
          <a-button type="primary" @click="show">{{
            showFlag ? "显示" : "隐藏"
          }}</a-button>
          <p></p>
          <!-- 当这个组件的值变化后， myDirective 组件也会发生更新 -->
          <a-input v-myIf="showFlag" value="你能看见我么"></a-input>
        </div>
        <!-- 字面量 -->
        <a-divider></a-divider>
        <div v-demo="{ color: 'white', text: 'hello!' }">我在这里</div>
      </div></a-col
    >
    <a-col :span="12">
      <div class="clickDiv" v-ClickOutSide="clickOutSide">
        点我之外的区域都会打印点击的对象
      </div>
    </a-col>
  </a-row>
</template>

<script>
export default {
  data() {
    return {
      value: "我是值",
      baz: "baz",
      foo: "foo",
      showFlag: false,
    };
  },
  methods: {
    clickOutSide() {
      console.log("点了外面" + Math.random());
    },
    show() {
      this.showFlag = !this.showFlag;
    },
    /**
     * foo 变化后会触发 v-example 的变化
     */
    change() {
      this.foo = "fooo";
    },
  },
  /**
   * 如果不在 <script setup> 标签下，需要使用 directives
   * 这会在 `mounted` 和 `updated` 时都调用
   */
  directives: {
    ClickOutSide: {
      mounted(el, binding) {
        function eventHandler(e) {
          // 可以检测出当前元素 e 是否是 el 的子节点（后节点）
          if (el.contains(e.target)) {
            return false;
          }
          // 如果绑定的参数是函数，正常情况也应该是函数，执行
          if (binding.value && typeof binding.value === "function") {
            // 执行方法，并将节点 e 传递到方法中
            binding.value(e);
          }
        }
        // 用于销毁前注销事件监听
        el.__click_outside__ = eventHandler;
        // 添加事件监听,触发时会发送当前 dom 元素对象
        document.addEventListener("click", eventHandler);
      },
      beforeUnmount(el) {
        // 移除事件监听
        document.removeEventListener("click", el.__click_outside__);
        // 删除无用属性
        delete el.__click_outside__;
      },
    },
    demo: (el, binding) => {
      console.log(binding.value.color);
      console.log(binding.value.text);
    },
    /**
     * 一个很常见的情况是仅仅需要在 mounted 和 updated 上实现相同的行为，除此之外并不需要其他钩子。
     * 这种情况下我们可以直接用一个函数来定义指令,这会在 `mounted` 和 `updated` 时都调用
     */
    myIf: (el, binding) => {
      if (binding.value == true) {
        el.style.display = "none";
      } else {
        el.style.display = "block";
      }
    },
    focus: {
      mounted: (el) => el.focus(),
    },
    example: {
      mounted: (el, binding) => {
        console.log(binding);
      },
      updated(el, binding) {
        console.log(binding);
      },
    },
    myDirective: {
      // 在绑定元素的 attribute 前
      // 或事件监听器应用前调用
      // eslint-disable-next-line no-unused-vars
      created(el, binding, vnode, prevVnode) {
        // 下面会介绍各个参数的细节
      },
      // 在元素被插入到 DOM 前调用
      // eslint-disable-next-line no-unused-vars
      beforeMount(el, binding, vnode, prevVnode) {},
      // 在绑定元素的父组件
      // 及他自己的所有子节点都挂载完成后调用
      // eslint-disable-next-line no-unused-vars
      mounted(el, binding, vnode, prevVnode) {},
      // 绑定元素的父组件更新前调用
      // eslint-disable-next-line no-unused-vars
      beforeUpdate(el, binding, vnode, prevVnode) {},
      // 在绑定元素的父组件
      // 及他自己的所有子节点都更新后调用
      // eslint-disable-next-line no-unused-vars
      updated(el, binding, vnode, prevVnode) {
        console.log(el);
        console.log(binding);
        console.log(vnode);
        console.log(prevVnode);
      },
      // 绑定元素的父组件卸载前调用
      // eslint-disable-next-line no-unused-vars
      beforeUnmount(el, binding, vnode, prevVnode) {},
      // 绑定元素的父组件卸载后调用
      // eslint-disable-next-line no-unused-vars
      unmounted(el, binding, vnode, prevVnode) {},
    },
  },
};
</script>

<!-- <script setup>
const vFocus = {
  mounted: (el) => el.focus(),
};
</script> -->

<style>
.clickDiv {
  background-color: greenyellow;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-around;
  flex-direction: column;
}
</style>
